#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int TEST_CASES = 25; // 生成25个测试用例
random_device rd;
mt19937 gen(rd());

// 生成一个随机整数
int randomInt(int min, int max) {
    return uniform_int_distribution<int>(min, max)(gen);
}

// 生成测试用例
void test(int testCase, ofstream& fout) {
    int t = 1;  // 测试用例数量
    int n, m, x, y;  // 节点数、边数、起点、终点
    vector<pair<int, int>> edges;  // 存储边的信息
    
    // 根据测试用例编号生成不同难度的测试数据
    if (testCase <= 5) {
        // 简单测试用例
        n = randomInt(2, 10);
        m = randomInt(n-1, min(n*(n-1)/2, 20));
    } else if (testCase <= 15) {
        // 中等测试用例
        n = randomInt(10, 100);
        m = randomInt(n-1, min(n*(n-1)/2, 500));
    } else {
        // 困难测试用例
        n = randomInt(100, 1000);
        m = randomInt(n-1, min(n*(n-1)/2, 5000));
    }
    
    // 根据测试用例类型生成不同特性的数据
    if (testCase == 1) {
        // 样例1 - 直接使用题目中的样例
        t = 2;
        fout << t << endl;
        
        // 第一个测试用例
        fout << "6 10 3 5" << endl;
        fout << "1 2" << endl;
        fout << "1 3" << endl;
        fout << "1 5" << endl;
        fout << "1 6" << endl;
        fout << "2 4" << endl;
        fout << "2 5" << endl;
        fout << "2 6" << endl;
        fout << "3 4" << endl;
        fout << "3 5" << endl;
        fout << "5 6" << endl;
        
        // 第二个测试用例
        fout << "3 2 3 2" << endl;
        fout << "1 3" << endl;
        fout << "2 3" << endl;
        
        return;
    } else if (testCase == 2) {
        // 线性图 (路径图)
        n = 1000;
        m = n - 1;
        x = 1;
        y = n;
        
        edges.clear();
        for (int i = 1; i < n; i++) {
            edges.push_back({i, i+1});
        }
    } else if (testCase == 3) {
        // 星形图 (所有节点都连接到中心节点)
        n = 1000;
        m = n - 1;
        x = 1;  // 中心节点
        y = randomInt(2, n);
        
        edges.clear();
        for (int i = 2; i <= n; i++) {
            edges.push_back({1, i});
        }
    } else if (testCase == 4) {
        // 完全图 (每个节点都与其他所有节点相连)
        n = 50;  // 较小的n，因为边数会很多
        m = n * (n - 1) / 2;
        x = randomInt(1, n);
        do {
            y = randomInt(1, n);
        } while (x == y);
        
        edges.clear();
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                edges.push_back({i, j});
            }
        }
    } else if (testCase == 5) {
        // 环形图
        n = 1000;
        m = n;
        x = 1;
        y = n/2;
        
        edges.clear();
        for (int i = 1; i < n; i++) {
            edges.push_back({i, i+1});
        }
        edges.push_back({n, 1});  // 闭合环
    } else {
        // 随机连通图
        x = randomInt(1, n);
        do {
            y = randomInt(1, n);
        } while (x == y);
        
        // 先生成一棵树确保图是连通的
        vector<bool> visited(n+1, false);
        visited[1] = true;
        edges.clear();
        
        for (int i = 2; i <= n; i++) {
            int parent = randomInt(1, i-1);
            edges.push_back({parent, i});
        }
        
        // 添加额外的边直到达到所需的边数
        set<pair<int, int>> edgeSet;
        for (auto& edge : edges) {
            edgeSet.insert({min(edge.first, edge.second), max(edge.first, edge.second)});
        }
        
        while (edges.size() < m) {
            int u = randomInt(1, n);
            int v = randomInt(1, n);
            if (u != v) {
                pair<int, int> newEdge = {min(u, v), max(u, v)};
                if (edgeSet.find(newEdge) == edgeSet.end()) {
                    edges.push_back({u, v});
                    edgeSet.insert(newEdge);
                }
            }
        }
    }
    
    // 输出测试数据
    fout << t << endl;
    fout << n << " " << m << " " << x << " " << y << endl;
    
    // 随机打乱边的顺序
    shuffle(edges.begin(), edges.end(), gen);
    
    for (auto& edge : edges) {
        fout << edge.first << " " << edge.second << endl;
    }
}

void mk_in() {
    // 创建testdata目录（如果不存在）
    if (system("mkdir -p testdata") != 0) {
        cerr << "创建testdata目录失败" << endl;
        return;
    }
    
    for (int i = 1; i <= TEST_CASES; ++i) {
        string in_name = "testdata/" + to_string(i) + ".in";
        ofstream fout(in_name);
        test(i, fout);
        fout.close();
        cout << "生成【" << i << ".in】数据成功\n";
    }
}

void mk_out() {
    for (int i = 1; i <= TEST_CASES; ++i) {
        string in_name = "testdata/" + to_string(i) + ".in";
        string out_name = "testdata/" + to_string(i) + ".out";
        string cmd = "./std < " + in_name + " > " + out_name;
        if (system(cmd.c_str()) != 0) {
            cerr << "生成【" << i << ".out】数据失败\n";
            return;
        }
        cout << "生成【" << i << ".out】数据成功\n";
    }
}

int main() {
    // 编译标准程序
    if (system("g++ std.cpp -o std -std=c++17") != 0) {
        cerr << "编译标准程序失败" << endl;
        return 1;
    }
    
    mk_in();
    mk_out();
    return 0;
}